﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ConnectViewModel.cs" company="R.V.Kasner">
//   Copyright © 2011 R.V.Kasner
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Owen.Terminal.ViewModel
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Windows.Input;

    using GalaSoft.MvvmLight.Command;

    using Microsoft.Practices.Prism.Events;

    using Owen.Communication.Service;
    using Owen.Terminal.Commons;
    using Owen.Terminal.Controllers;
    using Owen.Terminal.Events;
    using Owen.Terminal.View;

    public sealed class ConnectViewModel : ViewModelBase<IConnectView>, IConnectViewModel
    {
        private readonly ICommand breakCommand;

        private readonly ICommand breakTransmitCommand;

        private readonly ObservableCollection<VisualCommand> commandList;

        private readonly IEventAggregator eventAggregator;

        private readonly ICommand listenCommand;

        private readonly ICommand openFileCommand;

        private bool isReceive;

        private bool isTransmit;

        public ConnectViewModel()
        {
        }

        public ConnectViewModel(
            IConnectView view, 
            IEventAggregator eventAggregator,
            KeyRegistry keyRegistry, 
            IConnectController connectController)
            : base(view)
        {
            this.isTransmit = false;
            this.isReceive = false;

            this.commandList = new ObservableCollection<VisualCommand>();
            this.eventAggregator = eventAggregator;

            this.breakCommand = new RelayCommand(
                connectController.FullStop, 
                () => this.isReceive);

            this.breakTransmitCommand = new RelayCommand(
                connectController.StopTransmit,
                () => this.isTransmit);

            this.listenCommand = new RelayCommand(
                connectController.StartReceive,
                () => !this.isReceive);

            this.openFileCommand = new RelayCommand(
                () => this.eventAggregator.GetEvent<TryOpenDeviceConfigFileEvent>().Publish(null));

            this.eventAggregator.GetEvent<ConnectChangeEvent>().Subscribe(
                cc =>
                    {
                        this.isTransmit = (cc & SignallerStates.Transmit) == SignallerStates.Transmit;
                        this.isReceive = (cc & SignallerStates.Reseive) == SignallerStates.Reseive;
                        this.RaisePropertyChanged("IsPossibleTransfer");
                        CommandManager.InvalidateRequerySuggested();
                    });

            this.eventAggregator.GetEvent<VisualCommandsChangeEvent>().Subscribe(this.OnVisualCommandChange);

            keyRegistry.RegisterCommand(KeyNames.OpenPort, this.listenCommand);
            keyRegistry.RegisterCommand(KeyNames.ClosePort, this.breakCommand);
            keyRegistry.RegisterCommand(KeyNames.StopTransmit, this.breakTransmitCommand);
        }

        public ICommand BreakCommand
        {
            get
            {
                return this.breakCommand;
            }
        }

        public ICommand BreakTransmitCommand
        {
            get
            {
                return this.breakTransmitCommand;
            }
        }

        public ICommand ListenCommand
        {
            get
            {
                return this.listenCommand;
            }
        }

        public ICommand OpenFileCommand
        {
            get
            {
                return this.openFileCommand;
            }
        }

        public bool IsPossibleTransfer
        {
            get
            {
                return !this.isTransmit;
            }
        }

        public IEnumerable<VisualCommand> VisualCommands
        {
            get
            {
                return this.commandList;
            }
        }

        private void OnVisualCommandChange(IEnumerable<VisualCommand> visualCommands)
        {
            this.commandList.Clear();
            if (visualCommands == null) return;
            foreach (var command in visualCommands)
            {
                this.commandList.Add(command);
            }
        }
    }
}